Use case: conversion by interruption

Description of usage

Operation

HAL1

HAL2

Start conversion

Activate the ADC peripheral and start conversions in interrupt mode using:

  • HAL_ADC_Start_IT() for the regular group.

  • HAL_ADCEx_InjectedStart_IT() for the injected group.

Activate the ADC peripheral and start conversions using HAL_ADC_Start().

Note

From this point, the ADC internal analog hardware is enabled, inducing a slight current consumption.

Start the conversion with a trigger using:

  • HAL_ADC_REG_StartConv_IT() for the regular group.

  • HAL_ADC_INJ_StartConv_IT() for the injected group.

Note

Conversion trigger can be:

  • A software start: calls the function for each conversion.

  • From another peripheral (timer, for instance): calls the function once.

Calibration (optional)

  • Start calibration using HAL_ADCEx_Calibration_Start().

  • Get calibration value using HAL_ADCEx_Calibration_GetValue().

  • Set calibration value using HAL_ADCEx_Calibration_SetValue().

  • Calibrate the ADC using HAL_ADC_Calibrate().

  • Get calibration factor using HAL_ADC_GetCalibrationFactor().

  • Set calibration factor using HAL_ADC_SetCalibrationFactor().

Conversion complete callback

Implement the callback using:

  • HAL_ADC_ConvCpltCallback() for the regular group, which is called when the conversion is complete.

  • HAL_ADCEx_InjectedConvCpltCallback() for the injected group, which is called when the conversion is complete.

Implement the callback using:

  • HAL_ADC_REG_UnitaryConvCpltCallback() for the regular group, which is called when the conversion is complete.

  • HAL_ADC_RegisterInjUnitaryConvCpltCallback() for the injected group, which is called when the conversion is complete.

Retrieve conversion results

Retrieve conversion results using:

  • HAL_ADC_GetValue() for the regular group.

  • HAL_ADCEx_InjectedGetValue for the injected group.

Retrieve conversion results using:

  • HAL_ADC_REG_GetValue() for the regular group.

  • HAL_ADC_INJ_GetValue for the injected group.

Stop conversion

Stop potential ongoing conversions and disable the ADC peripheral using:

  • HAL_ADC_Stop_IT() for the regular and injected group.

  • HAL_ADCEx_RegularStop_IT() for the regular group.

  • HAL_ADCEx_InjectedStop_IT() for the injected group.

If the conversion trigger is not a software start (such as from another peripheral like a timer), stop the conversion using:

  • HAL_ADC_REG_StopConv_IT() for the regular group.

  • HAL_ADC_INJ_StopConv_IT() for the injected group.

Stop the ADC using HAL_ADC_Stop().

Loop for multiple iterations

N/A

Multiple iterations for starting and stopping conversions are possible.

Warning

If multiple conversions are required, do not fully stop the ADC using the HAL_ADC_Stop() function.

Sequence diagram

ADC interruption mode

@startuml

participant "User application\n(thread mode)" as appli
participant "User application\n(handler mode)" as appli_IRQ
participant "<font color=green><b>HAL ADC</b></font>" as ADC
participant "System HW interruption" as interruption

group#Linen ADC operation

  appli->ADC : <font color=green><b>HAL_ADC_Start_IT() <font color=black>/ <font color=blue><b>HAL_ADCEx_InjectedStart_IT()
  return

ADC->ADC : Enable ADC selected interruptions\nEnable ADC conversion trigger
interruption <[#purple]-x? : <font color=purple><b>ADC IRQ event
interruption -> appli_IRQ : ADCx_IRQHandler()
activate appli_IRQ #DarkSalmon
appli_IRQ -> ADC : HAL_ADC_IRQHandler()

return
ADC -> ADC : Clear flag

  ADC -> appli_IRQ: <font color=green><b>HAL_ADC_ConvCpltCallback() <font color=black>/ <font color=blue><b>HAL_ADCEx_InjectedConvCpltCallback()
  return
  appli_IRQ->ADC : <font color=green><b>HAL_ADC_GetValue() <font color=black>/ <font color=blue><b>HAL_ADCEx_InjectedGetValue()
  ADC --> appli_IRQ
  appli_IRQ -> interruption : (return from ISR)
  deactivate appli_IRQ
  appli->ADC : <font color=green><b>HAL_ADC_Stop_IT() <font color=black>/ <font color=blue><b>HAL_ADCEx_InjectedStop_IT()
  return

@enduml

Code snippet

HAL1

HAL2

Regular group use case

int main(void)
{
    // Add your Init and config code

    /* Start the ADC conversion in interrupt mode */
    HAL_ADC_Start_IT(&hadc1);

    // Wait flag end of conversion raised

    HAL_ADC_Stop_IT(&hadc1);

}

/* ADC conversion complete callback */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
    if (hadc->Instance == ADC1)
    {
        /* Read the ADC value */
        adcValue = HAL_ADC_GetValue(hadc);
        /* Add your processing code here */
    }
}

/* ADC analog watchdog callback */
void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc)
{
     /* Handle the analog watchdog event
        Add your processing code here  */
}

/* ADC interrupt handler */
void ADC1_IRQHandler(void)
{
    HAL_ADC_IRQHandler(&hadc1);
}

Regular group use case

int main(void)
{
    hal_status_t hal_status;

    // Add your Init and config code

    // Set your AWD thresholds using HAL_ADC_SetAnalogWDThresholds()

    /* Start the ADC conversion in interrupt mode */
    HAL_ADC_Start(&hadc1);
    while (1)
    {
        /* ========== ADC measurement ========== */
        hal_status |= HAL_ADC_REG_StartConv_IT_Opt(&hadc1, HAL_ADC_OPT_IT_REG_EOC | HAL_ADC_OPT_IT_AWD_1);

        // Wait flag end of conversion raised

        /* Stop the ADC conversion in interrupt mode */
        HAL_ADC_REG_StopConv_IT(&hadc1);
    }
    /* ADC stop */
    hal_status |= HAL_ADC_Stop(&hadc1);
}

/* ADC conversion complete callback */
void HAL_ADC_REG_UnitaryConvCpltCallback(hal_adc_handle_t *hadc)
{
   /* Read the ADC value */
   adcValue = HAL_ADC_REG_GetValue(hadc);

}

/* ADC analog watchdog callback */
void HAL_ADC_AnalogWD_OutOfWindowCallback(hal_adc_handle_t *hadc, hal_adc_awd_instance_t awd_instance)
{
    if (awd_instance == HAL_ADC_AWD_1)
    {
        // Handle the analog watchdog event
        // Add your processing code here
    }
}

/* ADC interrupt handler */
void ADC1_IRQHandler(void)
{
    HAL_ADC_IRQHandler(&hadc1);
}

Injected group use case

int main(void)
{
    // Add your Init and config code

    /* Start the ADC conversion in interrupt mode */
    HAL_ADCEx_InjectedStart_IT(&hadc1);

    // Wait flag end of conversion raised

    /* Stop  the ADC conversion in interrupt mode */
    HAL_ADCEx_InjectedStop_IT(&hadc1);

}

/* ADC conversion complete callback */
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{
    if (hadc->Instance == ADC1)
    {
         /* Read the ADC injected values */
        injectedValue1 = HAL_ADCEx_InjectedGetValue(hadc, ADC_INJECTED_RANK_1);
        injectedValue2 = HAL_ADCEx_InjectedGetValue(hadc, ADC_INJECTED_RANK_2);
         /* Add your processing code here */
    }
}

/* ADC analog watchdog callback */
void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc)
{
    if (hadc->Instance == ADC1)
    {
        // Handle the analog watchdog event
        // Add your processing code here
    }
}

/* ADC interrupt handler */
void ADC1_IRQHandler(void)
{
    HAL_ADC_IRQHandler(&hadc1);
}

Injected group use case

int main(void)
{
    hal_status_t hal_status;

    // Add your Init and config code

    // Set your AWD thresholds using HAL_ADC_SetAnalogWDThresholds()

     /* Start the ADC conversion in interrupt mode */
    HAL_ADC_Start(&hadc1);
    while (1)
    {
        /* ========== ADC measurement ========== */
        hal_status |= HAL_ADC_INJ_StartConv_IT(&hadc1, HAL_ADC_OPT_IT_REG_EOC | HAL_ADC_OPT_IT_AWD_1);

        // Wait flag end of conversion raised

         /* Stop the ADC conversion in interrupt mode */
        HAL_ADC_INJ_StopConv_IT(&hadc1);
    }
     /* ADC stop */
    hal_status |= HAL_ADC_Stop(&hadc1);
}

 /* ADC conversion complete callback */
void HAL_ADC_RegisterInjUnitaryConvCpltCallback(hal_adc_handle_t *hadc)
{
    /* Read the ADC value */
   adcValue = HAL_ADC_INJ_GetValue (hadc,1);
    /* Add your processing code here */
}

 /* ADC analog watchdog callback */
void HAL_ADC_AnalogWD_OutOfWindowCallback(hal_adc_handle_t *hadc, hal_adc_awd_instance_t awd_instance)
{
    if (awd_instance == HAL_ADC_AWD_1)
    {
        // Handle the analog watchdog event
        // Add your processing code here
    }
}

 /* ADC interrupt handler */
void ADC1_IRQHandler(void)
{
    HAL_ADC_IRQHandler(&hadc1);
}

Key changes

  1. The split of the activate and start conversion functions in interrupt mode.

  2. The split of the disable and stop conversion functions in interrupt mode.

  3. In HAL2, use HAL_ADC_REG_StartConv_IT_Opt() instead of HAL_ADC_REG_StartConv_IT() to enable only specific interruptions, such as EOC and AWD1.